var sw = 20,   //一个方块的宽度
    sh = 20,   //一个方块的高度
    tr = 30,   //行数
    th =30;   //列数
var snake = null,  //蛇实例
    food = null,    //食物实例
    game = null;      //游戏实例

function Square(x,y,classname){     //方块构造函数
          //0,0            0,0
          //20,0           1,0
          //40,0           2,0

          this.x = x*sw;  //构造函数里面传入的x，y是小20倍的，所有乘20方块的大小就算她们创建的初始位置
          this.y = y*sh;
          this.class = classname;  //名字也是

          this.viewContent = document.createElement('div');  //创建一个方块
          this.viewContent.className = this.class;           //class名给上
          this.parent = document.getElementById('snakeWrap'); //对应上他的父级，不让他脱离了父级（游戏）范围
}
Square.prototype.create=function(){          //给方块的原型加创造函数->样式
    this.viewContent.style.position = 'absolute';  //加绝对定位
    this.viewContent.style.widt=sw+'px';            //给宽
    this.viewContent.style.height=sh+'px';          //给高
    this.viewContent.style.left = this.x+'px';      //加右偏移量
    this.viewContent.style.top=this.y+'px';         //加上偏移量
    this.parent.appendChild(this.viewContent);      //挂在父级里

}
Square.prototype.remove = function(){      //原型加入remove方法，删除方块 
    this.parent.removeChild(this.viewContent); 
}

function Snake(){       //创建蛇
    this.head = null;   //存蛇头信息
    this.tail = null;   //存蛇尾tail信息
    this.pos = [];      //存蛇整体信息pos，用数组

    this.directionNum = {   //存方位 directionNum，用对象来表示
        left:{
            x:-1,
            y:0,
            rotate:180
        },
       right:{
            x:1,
            y:0,
            rotate:0
        },
        up:{
            x:0,
            y:-1,
            rotate:-90
        },
        down:{
            x:0,
            y:1,
            rotate:90
        }
    }
}
Snake.prototype.init = function(){   //蛇的原型上init，创建蛇

    var snakeHead = new Square(2,0,'snakeHead');   //创建蛇头
    snakeHead.create();
    this.head=snakeHead;     //存蛇头信息
    this.pos.push([2,0]);    //把蛇头的位置存起来

    var snakeBody1 = new Square(1,0,'snakeBody');  //创建蛇身snakeBody1 
    snakeBody1.create();   //存蛇身信息
    this.pos.push([1,0]);  //把蛇身的位置存起来

    var snakeBody2 = new Square(0,0,'snakeBody');  //创建蛇尾snakeBody2
    snakeBody2.create();      
    this.tail = snakeBody2;   //存蛇尾信息
    this.pos.push([0,0]);      //把蛇尾的位置存起来

//让蛇整体形成链表关系，这样移动时以链表的属性形式，整体移动
    snakeHead.last = null;
    snakeHead.next = snakeBody1;

    snakeBody1.last = snakeHead;
    snakeBody1.next = snakeBody2;

    snakeBody2.last = snakeBody1;
    snakeBody2.next = null;

    this.direction =this.directionNum.right; //起始蛇的走向

};


Snake.prototype.getNextPos = function(){  //蛇原型方法，蛇头的下一个移动位置getNextPos 
    var nextPos = [                       //nextPos下个位置的坐标
        this.head.x/sw + this.direction.x,
        this.head.y/sh + this.direction.y,
    ]


    var selfCollied=false;  //判断是否撞到自己，selfCollied为false是没有撞到
    this.pos.forEach(function(value){     
        if(value[0]==nextPos[0]&&value[1]==nextPos[1]){  //遍历pos，看看有没有撞到自己
            selfCollied =true;                           //selfCollied = true
        }
    });
    if(selfCollied){                                   //如果撞到了自己，结束循环
        console.log('撞到自己了！');
        this.strategies.die.call(this);
        return;
    }

    if(nextPos[0]<0||nextPos[1]<0||nextPos[0]>th-1||nextPos[1]>tr-1){ //如果撞墙了
        console.log('撞墙了');
        this.strategies.die.call(this);
        return;
    }

    if(food&&food.pos[0]==nextPos[0]&&food.pos[1]==nextPos[1]){     //如果吃到食物了
        console.log('吃到食物啦');
        this.strategies.eat.call(this);
        return;
    }

    this.strategies.move.call(this);

}
Snake.prototype.strategies = {     //用strategies方法表示蛇的行为
    move:function(format){         //移动行为

        var newBody = new Square(this.head.x/sw,this.head.y/sh,'snakeBody');//new一个新蛇身体，代替之前的蛇头

        newBody.next = this.head.next;    //新身体的链表关系
        newBody.next.last = newBody;
        newBody.last = null;

        this.head.remove();              //去掉蛇头
        newBody.create();                //创建新的蛇身

        var newHead = new Square(this.head.x/sw+this.direction.x,this.head.y/sh+
            this.direction.y,'snakeHead'); //new一个新的蛇头

            newHead.next = newBody;        //新蛇头的链表关系
            newHead.last= null;
            newBody.last = newHead;
            newHead.viewContent.style.transform = 'rotate('+this.direction.rotate+'deg)';//新蛇头的走向，css3旋转角度
            newHead.create();     //创建蛇头


            this.pos.splice(0,0,[this.head.x/sw+this.direction.x,this.head.y/sh+this.direction.y]);//新的蛇头加进去pos里
            this.head = newHead;  //存新头的信息

            if(!format){    //如果没吃到食物
               this.tail.remove();  //删除蛇尾
               this.tail = this.tail.last;  //新蛇尾的信息就是原来蛇尾的last
               this.pos.pop();            //把去掉的蛇尾的pos里的位置信息也pop（）掉
            }
    },
    eat:function(){             //吃的行为
        this.strategies.move.call(this,true);
        createFood();          //创建食物       
        game.score++;          //吃到食物，score++分数
    },
    die:function(){           //死亡       
        game.over();          //游戏结束
    }
}
snake = new Snake();


function createFood(){             //创建食物的函数

    var x = null;                 //食物的x坐标信息，null
    var y = null;                 //食物的x坐标信息，null

    var include = true;          //用include来控制食物的生成，其实是true       

    while(include){               
        x=Math.round(Math.random()*(th-1));   //随机生成食物
        y=Math.round(Math.random()*(tr-1));

        snake.pos.forEach(function(value){     //随机生成的食物不能在蛇的身体上
            if(x!=value[0]&&y!=value[1]){
                include=false;
            }
        });
    }

    food=new Square(x,y,'food');             //new一个food
    food.pos=[x,y];                          //添加食物坐标进去

    var foodDom=document.querySelector('.food'); //匹配food给fooDom 
    if(foodDom){                              //如果页面中有食物，给他位置，没有则创建                
        foodDom.style.left=x*sw+'px';
        foodDom.style.top=y*sh+'px';
    }else{
        food.create();
    }
}

function Game(){                  //创建游戏函数，里面有时间，score
    this.timer=null;              
    this.score=0;

}
Game.prototype.init=function(){     //init初始化函数    
    snake.init();
    createFood();

    document.onkeydown=function(ev){       //键盘按下事件，判断蛇的上下左右行动
        if(ev.which == 37&&snake.direction!=snake.directionNum.right){
            snake.direction=snake.directionNum.left;
        }else if(ev.which==38&&snake.direction!==snake.directionNum.down){
            snake.direction = snake.directionNum.up;
        }else if(ev.which==39&&snake.direction!=snake.directionNum.left){
            snake.direction = snake.directionNum.right;
        }else if(ev.which==40&&snake.direction!=snake.directionNum.up){
            snake.direction = snake.directionNum.down;
        }
    }
    this.start();
}

Game.prototype.start=function(){         //开始游戏
    this.timer=setInterval(function(){
        snake.getNextPos();
    },50)
}
Game.prototype.pause=function(){        //暂停游戏
    clearInterval(this.timer);
}
Game.prototype.over=function(){         //游戏结束
    clearInterval(this.timer);
    alert('你的得分是:'+this.score);

    var snakeWrap=document.getElementById('snakeWrap');
    snakeWrap.innerHTML='';

    snake=new Snake();
    game=new Game();
    
    var startBtnWrap = document.querySelector('.startBtn');
    startBtnWrap.style.display='block';
}

//开启游戏
game=new Game();
var startBtn=document.querySelector('.startBtn button');
startBtn.onclick=function(){         
    startBtn.parentNode.style.display='none';
    game.init();
} 
//暂停
var snakeWrap=document.getElementById('snakeWrap');
var pauseBtn=document.querySelector('.pauseBtn button');
snakeWrap.onclick=function(){     //点击暂停
    game.pause();
    pauseBtn.parentNode.style.display='block';

}
pauseBtn.onclick=function(){     //暂停界面点击开始游戏
    game.start();
    pauseBtn.parentNode.style.display='none';
}